from pyFAMOUSO.publisher import PublisherEventChannel
from abstract_node.datasheet_parser import EventDataSheetParser

import time
from auxillaries.QtFrameMatplotlib import QtFrameMatplotlib
from auxillaries.QtFrameMatplotlib import worker
from PyQt4 import QtCore, QtGui
import pylab as pylab
import numpy
import sys
from threading import Thread
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

class OutputInterfaceToConsole():
    
    def __init__(self, eventDataSheet):
        
        self.parser=EventDataSheetParser(filename=eventDataSheet)
        self.properties=self.parser.load_event_datasheet()
    
    def output_control(self, event):
        if event.is_complete():
            event.content=event.event_encoding()
            self.output(event)
        else:
            print "Incomplete events are not published "
        
    def output(self,event):
        value=event.get_value('Measurement')
        output=str(value)
        print "%s - published to terminal - (%s)"%(self.properties.subject,
                                                    output)
        
    def __repr__(self):
        output = "Default output to console/n"
        return output

class OutputInterfaceToFAMOUSO(OutputInterfaceToConsole):

    def __init__(self, eventDataSheet):
        OutputInterfaceToConsole.__init__(self, eventDataSheet)
        self.pub = PublisherEventChannel(self.properties.subject)
        self.pub.announce(self.properties.subject)
    
    def output(self, event):
        self.pub.publish(event)

    def __repr__(self):
        output = "Middleware output/n"
        return output

class OutputInterfaceToGUI(OutputInterfaceToConsole):
    def __init__(self, eventDataSheet):
        OutputInterfaceToConsole.__init__(self, eventDataSheet)
    
    def output(self, event):
        pass
    
    def __repr__(self):
        output = "GUI output/n"
        return output
    
class OutputInterfaceToLogger(OutputInterfaceToConsole):
    def __init__(self,  appName, eventDataSheet, logger):
        OutputInterfaceToConsole.__init__(self, eventDataSheet)
        self.logger=logger
        
    def output(self, event):
        self.logger.info("%s Event"%self.subject)
        
    def __repr__(self):
        output = "Output to logger/n"
        return output

class OutputInterfaceToVTK(OutputInterfaceToConsole):
    def __init__(self,  eventDataSheet, VTKSensor):
        import vtk
        from vtk.util.colors import red, green, blue
        OutputInterfaceToConsole.__init__(self, eventDataSheet)
        self.VTKSensor=VTKSensor
        
    def output(self, event):
        try: 
            value=event.get_value('Measurement')
            if value.magnitude[0]==0 and value.magnitude[1]==0:
                self.VTKSensor.hideMeasurement()
            else:
                self.VTKSensor.showMeasurement( value.magnitude*100)
        except:
            print "GUI not ready yet!"
        
    def __repr__(self):
        output = "Output to VTK"
        return output

    
class OutputInterfaceToMatplotlib(OutputInterfaceToConsole):
    def __init__(self, eventDataSheet):

        OutputInterfaceToConsole.__init__(self, eventDataSheet) 
        self.ui=QtFrameMatplotlib()
        self.guiWorker=worker(self.ui)
        self.guiWorker.start()
        self.t_index_max=1000
        self.t_max=10                                 # seconds
        self.values=numpy.zeros(self.t_index_max)
        self.validity=numpy.zeros(self.t_index_max)
        self.last_timestamp=time.time()
        
    def output(self, event):
        value=event.get_value('Measurement')
        validity=event.get_value('Validity')
        new_timestamp=time.time()
        time_diff=(new_timestamp-self.last_timestamp)
        time_shift=int(time_diff* self.t_index_max/self.t_max)
        #print "time diff", time_diff, "time shift", time_shift
        self.last_timestamp=new_timestamp
        if time_diff<self.t_index_max:
            new_entries_value=numpy.zeros(time_shift)
            new_entries_value[:]=self.values[self.t_index_max-1]
            new_entries_validity=numpy.zeros(time_shift)
            new_entries_validity[:]=self.validity[self.t_index_max-1]
            if time_shift>0:
                new_entries_value[time_shift-1]=value
                new_entries_validity[time_shift-1]=validity[0]              
                self.values=numpy.concatenate((self.values[time_shift:],new_entries_value),1)
                self.validity=numpy.concatenate((self.validity[time_shift:],new_entries_validity),1)
            else:
                self.values[self.t_index_max-1]=value
                self.validity[self.t_index_max-1]=validity[0]              
        else:
            print "to do"
            
        try:
            self.ui.subject_label.setText(self.properties.subject)
            self.ui.value_label.setText(str(value))
            self.ui.line0.set_ydata(self.values)
            self.ui.line1.set_ydata(self.validity)
            self.ui.canvas0.draw()
        except:
            print "Error while matplotlib output"
        
    def __repr__(self):
        output = "Output to logger/n"
        return output